﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using IRemoting;
using System.IO;
using System.Threading;
using QLNH.QLNH_BUS_WS;
using System.Windows.Media.Imaging;

namespace QLNH
{
    public partial class MainPage : PhoneApplicationPage
    {
        private TcpClient tcpClient;
        private AccountDetailDTO currentAccount = null;
        private bool isModifyOrderMode = false;

        #region Properties

        #region OrderList

        public static readonly DependencyProperty OrderListProperty =
            DependencyProperty.Register("OrderList", typeof(ObservableCollection<OrderListItem>), typeof(MainPage), new PropertyMetadata((ObservableCollection<OrderListItem>)null));

        public ObservableCollection<OrderListItem> OrderList
        {
            get { return (ObservableCollection<OrderListItem>)GetValue(OrderListProperty); }
            set { SetValue(OrderListProperty, value); }
        }

        #endregion

        #region TotalCompletedOrder

        public static readonly DependencyProperty TotalCompletedOrderProperty =
            DependencyProperty.Register("TotalCompletedOrder", typeof(int), typeof(MainPage), new PropertyMetadata((int)0));

        public int TotalCompletedOrder
        {
            get { return (int)GetValue(TotalCompletedOrderProperty); }
            set { SetValue(TotalCompletedOrderProperty, value); }
        }

        #endregion

        #region TotalOrder

        public static readonly DependencyProperty TotalOrderProperty =
            DependencyProperty.Register("TotalOrder", typeof(int), typeof(MainPage), new PropertyMetadata((int)0));

        public int TotalOrder
        {
            get { return (int)GetValue(TotalOrderProperty); }
            set { SetValue(TotalOrderProperty, value); }
        }

        #endregion

        #region OrderMealList

        public static readonly DependencyProperty OrderMealListProperty =
            DependencyProperty.Register("OrderMealList", typeof(ObservableCollection<MealListItem>), typeof(MainPage), new PropertyMetadata((ObservableCollection<MealListItem>)null));

        public ObservableCollection<MealListItem> OrderMealList
        {
            get { return (ObservableCollection<MealListItem>)GetValue(OrderMealListProperty); }
            set { SetValue(OrderMealListProperty, value); }
        }

        #endregion

        #region CatalogDetail

        public static readonly DependencyProperty CatalogDetailProperty =
            DependencyProperty.Register("CatalogDetail", typeof(ObservableCollection<MealListItem>), typeof(MainPage), new PropertyMetadata((ObservableCollection<MealListItem>)null));

        public ObservableCollection<MealListItem> CatalogDetail
        {
            get { return (ObservableCollection<MealListItem>)GetValue(CatalogDetailProperty); }
            set { SetValue(CatalogDetailProperty, value); }
        }

        #endregion

        #region TableList

        public static readonly DependencyProperty TableListProperty =
            DependencyProperty.Register("TableList", typeof(ObservableCollection<TableListItem>), typeof(MainPage), new PropertyMetadata((ObservableCollection<TableListItem>)null));

        public ObservableCollection<TableListItem> TableList
        {
            get { return (ObservableCollection<TableListItem>)GetValue(TableListProperty); }
            set { SetValue(TableListProperty, value); }
        }

        #endregion

        #region CatalogList

        public static readonly DependencyProperty CatalogListProperty =
            DependencyProperty.Register("CatalogList", typeof(ObservableCollection<CatalogListItem>), typeof(MainPage), new PropertyMetadata((ObservableCollection<CatalogListItem>)null));

        public ObservableCollection<CatalogListItem> CatalogList
        {
            get { return (ObservableCollection<CatalogListItem>)GetValue(CatalogListProperty); }
            set { SetValue(CatalogListProperty, value); }
        }

        #endregion

        #region ProgressbarText

        public static readonly DependencyProperty ProgressbarTextProperty =
            DependencyProperty.Register("ProgresbarText", typeof(string), typeof(MainPage), new PropertyMetadata((string)""));

        public string ProgressbarText
        {
            get { return (string)GetValue(ProgressbarTextProperty); }
            set { SetValue(ProgressbarTextProperty, value); }
        }

        #endregion

        #region IsLoading

        public static readonly DependencyProperty IsLoadingProperty =
            DependencyProperty.Register("IsLoading", typeof(bool), typeof(MainPage), new PropertyMetadata((bool)false));

        public bool IsLoading
        {
            get { return (bool)GetValue(IsLoadingProperty); }
            set { SetValue(IsLoadingProperty, value); }
        }

        #endregion

        #endregion

        #region Contructor

        public MainPage()
        {
            InitializeComponent();
        }

        #endregion

        #region GUI

        private void showPanel(ApplicationPanels panel)
        {
            #region LoginPanel

            if (panel == ApplicationPanels.Login)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        LoginPanel.Visibility = Visibility.Visible;
                    });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        LoginPanel.Visibility = Visibility.Collapsed;
                    });
            }

            #endregion

            #region NewOrder

            if (panel == ApplicationPanels.NewOrder)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        NewOrderPanel.Visibility = Visibility.Visible;
                    });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        NewOrderPanel.Visibility = Visibility.Collapsed;
                    });
            }

            #endregion

            #region OrderList

            if (panel == ApplicationPanels.OrderList)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        OrderListPanel.Visibility = Visibility.Visible;
                        ApplicationBar.IsVisible = true;
                    });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        OrderListPanel.Visibility = Visibility.Collapsed;
                        ApplicationBar.IsVisible = false;
                    });
            }

            #endregion

            #region TableList

            if (panel == ApplicationPanels.TableList)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        SelectTablePanel.Visibility = Visibility.Visible;
                        getAllTable();
                    });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        SelectTablePanel.Visibility = Visibility.Collapsed;
                    });
            }

            #endregion

            #region MealList

            if (panel == ApplicationPanels.MealList)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        SelectMealPanel.Visibility = Visibility.Visible;
                        getAllCatalog();
                    });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                {
                    SelectMealPanel.Visibility = Visibility.Collapsed;
                });
            }

            #endregion
        }

        public void showLoading(string text, bool loading)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    ProgressbarText = text;
                    IsLoading = loading;
                });
        }

        #endregion

        #region Data communication

        private void connectToServer()
        {
            int port = Int32.Parse(Application.Current.Resources["RemoteServerPortNumber"].ToString());
            string ip = Application.Current.Resources["RemoteServerIP"].ToString();

            tcpClient = new TcpClient();

            try
            {
                tcpClient.Connect(ip, port);
                Worker worker = new Worker(this, tcpClient.GetStream());
                worker.work();
            }
            catch
            {
                MessageBox.Show("Có vấn đề về kết nối với máy chủ");
            }
        }

        #region Login

        private void login(string userName)
        {
            if (tb_userName.Text.Trim().Equals(""))
            {
                tb_loginMessage.Text = "* Tên đăng nhập không hợp lệ";
            }
            else
            {
                showLoading("Đang kết nối với máy chủ...", true);

                QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
                ws.GetAccoutInfoCompleted += new EventHandler<GetAccoutInfoCompletedEventArgs>(ws_GetAccoutInfoCompleted);
                ws.GetAccoutInfoAsync(userName);
            }
        }

        void ws_GetAccoutInfoCompleted(object sender, GetAccoutInfoCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                showLoading("Đang đang nhập...", true);

                string role = e.Result.Role;
                if (role != "waiter")
                {
                    showLoginReplyMessage("* Chỉ được đăng nhập bằng tài khoản waiter");
                    showLoading("", false);
                }
                else
                {
                    currentAccount = e.Result;

                    StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                    writer.AutoFlush = true;

                    BasePackage package = new BasePackage();
                    package.setHeader(PackageHeader.LOGIN_REQ);
                    package.setUserName(currentAccount.UserName);

                    try
                    {
                        writer.WriteLine(package.convertToString());
                    }
                    catch
                    {
                        MessageBox.Show("Có vấn đề về kết nối với máy chủ");
                        currentAccount = null;
                    }
                }
            }
            else
            {
                showLoading("", false);
                showLoginReplyMessage("* Tài khoản không tồn tại");
            }
        }

        public void showLoginReplyMessage(string message)
        {
            Dispatcher.BeginInvoke(() =>
            {
                tb_loginMessage.Text = message;
            });
        }

        #endregion

        #region Order

        // Converter
        private OrderListItem convertToOrderListItems(OrderDetailDTO orderDTO)
        {
            OrderListItem item = new OrderListItem()
            {
                OrderNo = orderDTO.OrderNo,
                TableID = orderDTO.TableID
            };

            switch (orderDTO.State)
            {
                case QLNH_BUS_WS.State.Modified:
                    item.State = QLNH.State.Modified;
                    Dispatcher.BeginInvoke(() => item.Image = Ultilities.GetImage("Modified.png"));
                    break;
                case QLNH_BUS_WS.State.New:
                    item.State = QLNH.State.New;
                    Dispatcher.BeginInvoke(() => item.Image = Ultilities.GetImage("New.png"));
                    break;
                case QLNH_BUS_WS.State.ReadyToServe:
                    item.State = QLNH.State.ReadyToServe;
                    Dispatcher.BeginInvoke(() => item.Image = Ultilities.GetImage("ReadyToServe.png"));
                    break;
            }

            return item;
        }

        // Get all order
        private void getAllOrder()
        {
            showLoading("Đang tải...", true);

            Dispatcher.BeginInvoke(() => OrderList = new ObservableCollection<OrderListItem>());

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.GetAllOrderForWaiterCompleted += new EventHandler<GetAllOrderForWaiterCompletedEventArgs>(ws_GetAllOrderForWaiterCompleted);
            ws.GetAllOrderForWaiterAsync();
        }

        void ws_GetAllOrderForWaiterCompleted(object sender, GetAllOrderForWaiterCompletedEventArgs e)
        {
            showLoading("", false);

            if (e.Error == null && e.Result != null)
            {
                Dispatcher.BeginInvoke(() => 
                    {
                        TotalOrder = e.Result.Count;
                        TotalCompletedOrder = 0;
                    });

                for (int i = 0; i < e.Result.Count; i++)
                {
                    OrderListItem item = convertToOrderListItems(e.Result[i]);

                    Dispatcher.BeginInvoke(() =>
                        {
                            OrderList.Add(item);

                            if (item.State == QLNH.State.ReadyToServe)
                            {
                                TotalCompletedOrder += 1;
                            }

                        });
                }
            }
        }

        // Get order
        private void getOrder(int orderNo)
        {
            showLoading("Đang tải...", true);

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.GetOrderCompleted += new EventHandler<GetOrderCompletedEventArgs>(ws_GetOrderCompleted);
            ws.GetOrderAsync(orderNo);
        }

        void ws_GetOrderCompleted(object sender, GetOrderCompletedEventArgs e)
        {
            showLoading("", false);

            if (e.Error == null)
            {
                if (e.Result != null)
                {
                    tb_tableNo.Text = e.Result.TableID;
                    tb_orderNo.Text = e.Result.OrderNo.ToString();

                    for (int i = 0; i < e.Result.Meals.Count; i++)
                    {
                        OrderMealList.Add(new MealListItem()
                        {
                            ID = e.Result.Meals[i].MealID,
                            Name = e.Result.Meals[i].MealName,
                            Amount = e.Result.Meals[i].Amount
                        });
                    }

                    showPanel(ApplicationPanels.NewOrder);
                }
            }
        }

        // Send order
        private void sendOrder()
        {
            if (tb_tableNo.Text.Trim().Equals(""))
            {
                MessageBox.Show("Chưa chọn bàn");
                return;
            }

            if (lb_mealList.Items.Count == 0)
            {
                MessageBox.Show("Chưa chọn món");
                return;
            }

            showLoading("Đang gửi...", true);

            OrderDetailDTO order = new OrderDetailDTO()
            {
                TableID = tb_tableNo.Text,
                OrderNo = Int32.Parse(tb_orderNo.Text),
                State = QLNH_BUS_WS.State.New,
                UserName = currentAccount.UserName,
                Meals = new ObservableCollection<OrderMealDTO>()
            };

            for (int i = 0; i < lb_mealList.Items.Count; i++)
            {
                OrderMealDTO meal = new OrderMealDTO()
                {
                    MealID = ((MealListItem)lb_mealList.Items[i]).ID,
                    MealName = ((MealListItem)lb_mealList.Items[i]).Name,
                    Amount = ((MealListItem)lb_mealList.Items[i]).Amount
                };

                order.Meals.Add(meal);
            }

            // 
            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.AddOrderCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ws_AddOrderCompleted);
            ws.AddOrderAsync(order, order);
        }

        void ws_AddOrderCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.AutoFlush = true;

                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.SEND_BROADCAST_MESSAGE);
                package.setBroadcastMassageHeader(BroadcastMassgeHeader.NEW_ORDER);
                package.setBroadcastMassage(tb_orderNo.Text);

                try
                {
                    // Send broadcast message to others
                    writer.WriteLine(package.convertToString());

                    // Add an order item to OrderList
                    OrderDetailDTO order = (OrderDetailDTO)e.UserState;
                    OrderListItem item = convertToOrderListItems(order);

                    OrderList.Add(item);
                    TotalOrder++;

                    showLoading("", false);
                    MessageBox.Show("Đặt món ăn thành công");

                    // Show the Order List Panel
                    showPanel(ApplicationPanels.OrderList);
                }
                catch
                {
                    showLoading("", false);
                    MessageBox.Show("Đặt món ăn thất bại");
                }
            }
            else
            {
                showLoading("", false);
                MessageBox.Show("Đặt món ăn thất bại");
            }
        }

        // Update order
        private void updateOrder()
        {
            if (tb_tableNo.Text.Trim().Equals(""))
            {
                MessageBox.Show("Chưa chọn bàn");
                return;
            }

            if (lb_mealList.Items.Count == 0)
            {
                MessageBox.Show("Chưa chọn món");
                return;
            }

            showLoading("Đang gửi...", true);

            OrderDetailDTO order = new OrderDetailDTO()
            {
                OrderNo = Int32.Parse(tb_orderNo.Text),
                State = QLNH_BUS_WS.State.Modified,
                TableID = tb_tableNo.Text,
                UserName = currentAccount.UserName
            };

            order.Meals = new ObservableCollection<OrderMealDTO>();

            for (int i = 0; i < lb_mealList.Items.Count; i++)
            {
                order.Meals.Add(new OrderMealDTO()
                {
                    MealID = ((MealListItem)lb_mealList.Items[i]).ID,
                    MealName = ((MealListItem)lb_mealList.Items[i]).Name,
                    Amount = ((MealListItem)lb_mealList.Items[i]).Amount
                });
            }

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.UpdateOrderCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ws_UpdateOrderCompleted);
            ws.UpdateOrderAsync(order, order);
        }

        void ws_UpdateOrderCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                // Send broadcast to others
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.AutoFlush = true;

                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.SEND_BROADCAST_MESSAGE);
                package.setBroadcastMassageHeader(BroadcastMassgeHeader.MODIFIED_ORDER);
                package.setBroadcastMassage(tb_orderNo.Text);

                try
                {
                    writer.WriteLine(package.convertToString());

                    OrderDetailDTO order = (OrderDetailDTO)e.UserState;

                    OrderListItem item = convertToOrderListItems(order);

                    // Reset attribute of updated OrderListItem
                    OrderList.First(o => o.OrderNo == item.OrderNo).Image = Ultilities.GetImage("Modified.png");
                    OrderList.First(o => o.OrderNo == item.OrderNo).OrderNo = item.OrderNo;
                    OrderList.First(o => o.OrderNo == item.OrderNo).State = item.State;
                    OrderList.First(o => o.OrderNo == item.OrderNo).TableID = item.TableID;

                    lb_orderList.ItemsSource = null;
                    lb_orderList.ItemsSource = OrderList;

                    showLoading("", false);
                    MessageBox.Show("Cập nhật món ăn thành công");

                    showPanel(ApplicationPanels.OrderList);
                }
                catch
                {
                    showLoading("", false);
                    MessageBox.Show("Cập nhật món ăn thất bại");
                }
            }
            else
            {
                showLoading("", false);
                MessageBox.Show("Cập nhật món ăn thất bại");
            }
        }

        // Genenrate the order no from server
        private void generateOrderNo()
        {
            showLoading("Đang tải...", true);

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.GenerateOrderNoCompleted += new EventHandler<GenerateOrderNoCompletedEventArgs>(ws_GenerateOrderNoCompleted);
            ws.GenerateOrderNoAsync();
        }

        void ws_GenerateOrderNoCompleted(object sender, GenerateOrderNoCompletedEventArgs e)
        {
            showLoading("", false);

            if (e.Error == null)
            {
                tb_orderNo.Text = e.Result.ToString();
            }
        }

        // Notify when an order is ready
        private void notifyReadyOrder(int orderNo)
        {
            Dispatcher.BeginInvoke(() =>
                {
                    TotalCompletedOrder++;

                    OrderList.First(e => e.OrderNo == orderNo).Image = Ultilities.GetImage("ReadyToServe.png");
                    OrderList.First(e => e.OrderNo == orderNo).State = QLNH.State.ReadyToServe;
                    lb_orderList.ItemsSource = null;
                    lb_orderList.ItemsSource = OrderList;
                });
        }

        private void servedOrder(int orderNo)
        {
            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.UpdateOrderStateCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(ws_UpdateOrderStateCompleted);
            ws.UpdateOrderStateAsync(orderNo, QLNH_BUS_WS.State.Served, orderNo);
        }

        void ws_UpdateOrderStateCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                int orderNo = (int)e.UserState;
                OrderList.Remove(OrderList.First(o => o.OrderNo == orderNo));
                TotalOrder--;
                TotalCompletedOrder--;

                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.SEND_BROADCAST_MESSAGE);
                package.setBroadcastMassageHeader(BroadcastMassgeHeader.SERVED_ORDER);
                package.setBroadcastMassage(orderNo.ToString());

                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.AutoFlush = true;

                try
                {
                    writer.WriteLine(package.convertToString());
                }
                catch
                {

                }
            }
        }

        #endregion

        #region Table

        private void getAllTable()
        {
            TableList = new ObservableCollection<TableListItem>();

            showLoading("Đang tải...", true);

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.GetAllEmptyTableCompleted += new EventHandler<GetAllEmptyTableCompletedEventArgs>(ws_GetAllEmptyTableCompleted);
            ws.GetAllEmptyTableAsync();
        }

        void ws_GetAllEmptyTableCompleted(object sender, GetAllEmptyTableCompletedEventArgs e)
        {
            showLoading("", false);

            if (e.Result != null && e.Error == null)
            {
                for (int i = 0; i < e.Result.Count; i++)
                {
                    TableList.Add(new TableListItem()
                    {
                        TableID = e.Result[i].ID,
                        Capacity = e.Result[i].Capacity
                    });
                }
            }
        }

        #endregion

        #region Meal

        private void getAllCatalog()
        {
            if (CatalogList == null)
            {
                showLoading("Đang tải...", true);

                CatalogList = new ObservableCollection<CatalogListItem>();

                QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
                ws.GetAllCatalogCompleted += new EventHandler<GetAllCatalogCompletedEventArgs>(ws_GetAllCatalogCompleted);
                ws.GetAllCatalogAsync();
            }
        }

        private void getAllMealOf(string catalogID)
        {
            showLoading("Đang tải...", true);

            CatalogDetail = new ObservableCollection<MealListItem>();

            QLNH_BUS_WebServiceSoapClient ws = new QLNH_BUS_WebServiceSoapClient();
            ws.GetAllMealDetailCompleted += new EventHandler<GetAllMealDetailCompletedEventArgs>(ws_GetAllMealDetailCompleted);
            ws.GetAllMealDetailAsync("", catalogID);
        }

        void ws_GetAllMealDetailCompleted(object sender, GetAllMealDetailCompletedEventArgs e)
        {
            showLoading("", false);
            if (e.Result != null)
            {
                for (int i = 0; i < e.Result.Count; i++)
                {
                    if (e.Result[i].Available == true)
                    {
                        CatalogDetail.Add(new MealListItem()
                        {
                            ID = e.Result[i].ID,
                            Name = e.Result[i].Name,
                            Price = e.Result[i].Price
                        });
                    }
                }
            }
        }

        void ws_GetAllCatalogCompleted(object sender, GetAllCatalogCompletedEventArgs e)
        {
            showLoading("", false);

            if (e.Result != null)
            {
                for (int i = 0; i < e.Result.Count; i++)
                {
                    CatalogList.Add(new CatalogListItem()
                    {
                        ID = e.Result[i].ID,
                        Name = e.Result[i].Name
                    });
                }
            }
        }

        #endregion

        #endregion

        #region Inner Class Worker

        // Worker thread to receiver message from remote server
        private class Worker
        {
            private MainPage mainPage;
            private Stream stream;

            public Worker(MainPage mainPage, Stream stream)
            {
                this.mainPage = mainPage;
                this.stream = stream;
            }

            public void work()
            {
                Thread t = new Thread(new ThreadStart(doWork));
                t.IsBackground = true;
                t.Start();
            }

            private void doWork()
            {
                StreamReader reader = new StreamReader(stream);
                while (true)
                {
                    string message = null;

                    try
                    {
                        message = reader.ReadLine();
                    }
                    catch
                    {
                        break;
                    }

                    if (message == null)
                    {
                        break;
                    }

                    BasePackage package = new BasePackage();
                    package.convertFromString(message);

                    switch (package.getHeader())
                    {
                        case PackageHeader.LOGIN_REQ_REP:
                            if (package.getLogginResult() == false)
                            {
                                string result = package.getLogginReplyMessage();
                                mainPage.showLoading("", false);
                                mainPage.showLoginReplyMessage(result);

                                mainPage.currentAccount = null;
                                
                            }
                            else
                            {
                                mainPage.showLoading("", false);
                                mainPage.showPanel(ApplicationPanels.OrderList);
                                mainPage.getAllOrder();
                            }
                            break;

                        case PackageHeader.SEND_BROADCAST_MESSAGE:

                            if (package.getBroadcastMassageHeader() == BroadcastMassgeHeader.READY_TO_SERVE_ORDER)
                            {
                                int orderNo = Int32.Parse(package.getBroadcastMassage());
                                mainPage.notifyReadyOrder(orderNo);
                            }

                            break;

                        default:
                            break;
                    }
                   
                }
            }
        }

        #endregion

        #region Control Events

        private void bt_login_Click(object sender, RoutedEventArgs e)
        {
            login(tb_userName.Text.Trim());
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.Login);
            connectToServer();
        }

        private void bt_selectTable_Click(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.TableList);
        }

        private void bt_addMeal_Click(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.MealList);
        }

        private void bt_decrement_Click(object sender, RoutedEventArgs e)
        {
            if (lb_mealList.SelectedItem != null)
            {
                MealListItem item = (MealListItem)lb_mealList.SelectedItem;
                if (item.Amount > 1)
                {
                    OrderMealList.First(i => i.ID.Equals(item.ID)).Amount--;
                    lb_mealList.ItemsSource = null;
                    lb_mealList.ItemsSource = OrderMealList;
                }
            }
        }

        private void bt_deleteRow_Click(object sender, RoutedEventArgs e)
        {
            if (lb_mealList.SelectedItem != null)
            {
                string id = ((MealListItem)lb_mealList.SelectedItem).ID;

                OrderMealList.Remove(OrderMealList.First(item => item.ID.Equals(id)));
            }
        }

        private void bt_increment_Click(object sender, RoutedEventArgs e)
        {
            if (lb_mealList.SelectedItem != null)
            {
                MealListItem item = (MealListItem)lb_mealList.SelectedItem;
                OrderMealList.First(i => i.ID.Equals(item.ID)).Amount++;
                lb_mealList.ItemsSource = null;
                lb_mealList.ItemsSource = OrderMealList;
            }
        }

        private void bt_sentOrder_Click(object sender, RoutedEventArgs e)
        {
            if (!isModifyOrderMode)
            {
                sendOrder();
            }
            else
            {
                updateOrder();
            }           
        }

        private void bt_cacelOrder_Click(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.OrderList);
        }

        private void bt_newOrder_Click(object sender, EventArgs e)
        {
            isModifyOrderMode = false;

            showPanel(ApplicationPanels.NewOrder);
            tb_tableNo.Text = "";

            if (OrderMealList == null)
                OrderMealList = new ObservableCollection<MealListItem>();
            else
                OrderMealList.Clear();

            generateOrderNo();
        }

        private void bt_editOrder_Click(object sender, EventArgs e)
        {
            var item = lb_orderList.SelectedItem;

            if (item != null && (item as OrderListItem).State != QLNH.State.ReadyToServe)
            {
                isModifyOrderMode = true;

                if (OrderMealList == null)
                    OrderMealList = new ObservableCollection<MealListItem>();
                else
                    OrderMealList.Clear();

                getOrder(((OrderListItem)lb_orderList.SelectedItem).OrderNo);
            }
        }

        private void bt_servedOrder_Click(object sender, EventArgs e)
        {
            var item = lb_orderList.SelectedItem;

            if (item != null && (item as OrderListItem).State == QLNH.State.ReadyToServe)
            {
                int orderNo = (item as OrderListItem).OrderNo;
                servedOrder(orderNo);
            }
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (currentAccount != null)
            {
                StreamWriter writer = new StreamWriter(tcpClient.GetStream());
                writer.AutoFlush = true;

                BasePackage package = new BasePackage();
                package.setHeader(PackageHeader.LOGOUT_REQ);
                package.setUserName(currentAccount.UserName);

                try
                {
                    writer.WriteLine(package.convertToString());
                }
                catch
                {
                }
            }
        }

        private void bt_selectTableOK_Click(object sender, RoutedEventArgs e)
        {
            if (lb_tableList.SelectedItem != null)
            {
                showPanel(ApplicationPanels.NewOrder);
                tb_tableNo.Text = ((TableListItem)lb_tableList.SelectedItem).TableID.ToString();
            }
        }

        private void bt_selectMeal_add_Click(object sender, RoutedEventArgs e)
        {
            if (lb_catalogDetail.SelectedItem != null)
            {
                MealListItem item = (MealListItem)lb_catalogDetail.SelectedItem;
                int amount = Int32.Parse(tb_amount.Text);

                if (OrderMealList.Any(m => m.ID.Equals(item.ID)))
                {
                    MealListItem tmp = OrderMealList.First(m => m.ID.Equals(item.ID));
                    tmp.Amount += amount;

                    lb_mealList.ItemsSource = null;
                    lb_mealList.ItemsSource = OrderMealList;
                }
                else
                {
                    item.Amount = amount;
                    OrderMealList.Add(item);
                }
            }
        }

        private void bt_selectMeal_back_Click(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.NewOrder);
        }

        private void bt_decreAmount_Click(object sender, RoutedEventArgs e)
        {
            int amount = Int32.Parse(tb_amount.Text);
            if (amount > 1)
            {
                amount--;
                tb_amount.Text = amount.ToString();
            }
        }

        private void bt_increAmount_Click(object sender, RoutedEventArgs e)
        {
            int amount = Int32.Parse(tb_amount.Text);
            amount++;
            tb_amount.Text = amount.ToString();

        }

        private void lb_catalog_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lb_catalog.SelectedItem != null)
            {
                string id = ((CatalogListItem)lb_catalog.SelectedItem).ID;
                getAllMealOf(id);
            }
        }

        private void bt_selectTableCancel_Click(object sender, RoutedEventArgs e)
        {
            showPanel(ApplicationPanels.NewOrder);
        }

        #endregion
    }
}